This disclosure relates generally to optimization of program compilation in a data processing system and more specifically to selective speculative class-based optimization in the data processing system.
Just In Time (JIT) compilers for Java® traditionally specialize compiled code very aggressively according to a current state of a class hierarchy. The aggressive specialization is needed because the Java specification requires support for dynamic class loading, but in practice Java applications are not particularly dynamic. Accordingly optimizing code for a current state of a class hierarchy is most frequently an effective way to optimize the way in which a Java application continues to execute. Probability of correct optimization is increased by using assumptions, which are registered against classes that have been optimized by the JIT compiler so that, when an assumption about the state of the class hierarchy is later invalidated, the code can be corrected.
An example of this kind of optimization is method inlining for virtual methods. For example, using a method invocation to C.foo( ), when there is currently only one class D in a hierarchy rooted at class C that implements the foo( ) method, then the JIT compiler will inline (i.e., add to a section of code) the D.foo( ) code without an explicit check to detect that the receiver object is D or one of the associated subclasses.
The JIT compiler also registers assumptions on all subclasses of C that correspond to a condition in which the code inlined for the invocation to C.foo( ) depends there be no other implementation of foo( ), so when this class is later extended by a class that overrides the foo( ) method, the JIT compiler can correct the inlined code. Any class that extends the hierarchy of C automatically inherits this assumption so that a respective compensation occurs when the assumption the JIT compiler made becomes invalid. In practice, the assumption framework tends to be an extremely effective tool. Other, similar, types of speculation can be performed, but the types use properties of classes that are extensible in the Java language, such as overriding a virtual method, implementing an interface method, or simply extending a class.
Conventional implementations therefore have typically focused on proving the explicit checks are not needed or moving checks to places that execute less frequently.